# Class to make deferred requests to Google
=begin
Copyright (C) 2014 Enrique Rando

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

http://www.gnu.org/licenses/gpl-2.0.html
=end

=begin

THIS CLASS IS MEANT FOR EDUCATIONAL PURPOSES ONLY

IF YOU NEED TO USE THIS SEARCH ENGINE, PLEASE IMPLEMENT IT IN A RUBY CLASS AS INDICATED IN THE DOCUMENTATION USING THE APPROPIATE APIs

=end

=begin

WORKING IN PROGRESS

=end

class Google_deferred
	# Object creation
	# Parameters
	#		user_agent		User-agent to use in requests
	#		proxy			Proxy name or address. Use nil for no proxy.
	#						By default (:ENV), Ruby 2.1 uses HTTP_PROXY environment variable to set the proxy
	#		proxy_port		Proxy port
	#		proxy_user		Proxy username, if required
	#		proxy_password	Proxy password, if required.
	def initialize(user_agent, proxy=:ENV, proxy_port=nil, proxy_user=nil, proxy_password=nil)
		# Base URLs
		@base = "https://translate.googleusercontent.com/translate_c?act=url&depth=1&hl=en&ie=UTF8&prev=_t&rurl=translate.google.com&"
		@base_referer = "https://translate.google.com/translate"
		
		# Connect to server
		uri = URI.parse(@base_referer)
		@scheme = uri.scheme.to_sym
		@host = uri.host
		@port = uri.port
		
		connect_through(@proxy, @proxy_port, @proxy_user, @proxy_password)
	end
	
	# Establish connection
	# Parameters
	#		proxy			Proxy name or address. Use nil for no proxy.
	#						By default (:ENV), Ruby 2.1 uses HTTP_PROXY environment variable to set the proxy
	#		proxy_port		Proxy port
	#		proxy_user		Proxy username, if required
	#		proxy_password	Proxy password, if required.
	def connect_through(proxy=:ENV, proxy_port=nil, proxy_user=nil, proxy_password=nil)
		@proxy = proxy
		@proxy_port = proxy_port
		@proxy_user = proxy_user
		@proxy_password = proxy_password

		@client = My_HTTP_client.new(@user_agent, @proxy, @proxy_port, @proxy_user, @proxy_password)
		@client.set_server(@scheme, @host, @port)		
	end
	
	# Creates URLs for a result
	# Parameters
	#	type		Type of URL to create :cache, :translate
	#	result		Search Engine Result
	#	only_one	True if only one URL is needed. Useful for not making too much connections
	def get_info(type, result, only_one=false)
		case type
		when :translate
			url = result[:url]
			return translate(url, only_one)
		when :cache
			return nil
		else
			raise "Invalid info request: #{type.to_s}"
		end
	end
	
private	

	# Retrieve Translate URLs on demand
	# Parameters
	#	url			URL to translate
	#	only_one	True if only one URL is needed. Useful for not making too much connections
	def translate(url, only_one=false)	
		res = []
				
		# Process URLs
		# It takes two requests to translate a URL
		# The first one gets a token that will be used in the second one
		# Two translations are tried: Spanish to English and English to Spanish to circunvent problems with document languages
		[{"sl"=>"es", "tl"=>"en"}, {"sl"=>"en", "tl"=>"es"}].each do |params|
			# Make first request
			parameters = params.clone
			parameters["u"] = url
			referer = "#{@base_referer}?#{URI.encode_www_form(parameters)}"
			
			uri = URI.parse(referer)
			response = @client.get(uri.request_uri, {}, {})
			next if response.nil?
			
			# First request contains an IFRAME with the token
			match = response.body.to_s.match(/<iframe .*? src="(?<data>.*?)"/im)
			next if match.nil?
			
			# Get the token
			tr_url = match[:data]
			usg = tr_url.match(/.*usg=(?<data>.*?)$/)
			next if usg.nil?
			
			# Create the "translate" URL
			parameters["usg"] = usg[:data]
			new_url = "#{@base}#{URI.encode_www_form(parameters)}"
			res << {:url=>new_url, :referer=>referer}
			
			break if only_one
		end

		# Delete null URLs
		res.delete_if{|x| x[:url].nil?}
		return res.count==0 ? nil : res
	end
end
